import {
  useContext,
  createContext,
  Context,
  useEffect,
  FC,
  createElement,
  useState,
  useRef,
  useCallback,
} from 'react';
// import { config } from 'react-transition-group';

interface IPageConfig {
  appBarTitleText: string;
  appBarStyle: 'light' | 'none';
  loading: boolean;
  reload?: () => void;
}

const defaultConfig: IPageConfig = {
  appBarTitleText: '',
  appBarStyle: 'light',
  loading: false,
  reload: undefined,
};

interface IPageContext {
  config: IPageConfig;
  onConfigChange?: (config: IPageConfig) => void;
}

const PageContext = createContext<IPageContext>({
  config: defaultConfig,
});

export const PageProvider: FC = ({ children }) => {
  const [configState, setConfigState] = useState(defaultConfig);
  const handleConfigChange = useCallback((config: IPageConfig) => {
    if (compare(configState, config)) {
      document.title = `10喵喵的世界-${config.appBarTitleText}`;
      setConfigState(config);
    }
  }, []);

  return createElement(
    PageContext.Provider,
    {
      value: {
        config: configState,
        onConfigChange: handleConfigChange,
      },
    },
    children,
  );
};

export function usePageConfig(): IPageConfig {
  const context = useContext<IPageContext>(PageContext);
  return context.config;
}

type IPage = {
  [P in keyof IPageConfig]?: IPageConfig[P];
};

export function usePage(page?: IPage) {
  const context = useContext<IPageContext>(PageContext);
  const pageRef = useRef<IPage>({});
  const pageSY = useRef(0);
  useEffect(() => {
    if ((page && !pageRef.current) || compare(pageRef.current, page)) {
      pageRef.current = page || {};
      context.onConfigChange &&
        context.onConfigChange({ ...defaultConfig, ...page });
    }
  }, [page]);
}

function compare<T>(oldV: T, newV: T): boolean {
  if (oldV === newV) {
    return false;
  }
  const keys = Object.keys(newV) as Array<keyof T>;
  if (keys.length !== Object.keys(oldV).length) {
    return true;
  }
  return !!keys.find(key => oldV[key] !== newV[key]);
}
